package cn.liuhulu.controller;

import java.net.URL;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.stream.Collectors;

import cn.liuhulu.controller.ui.EditingCell;
import cn.liuhulu.data.Datas;
import cn.liuhulu.entity.Product;
import cn.liuhulu.entity.ProductBill;
import cn.liuhulu.tool.AlertMaker;
import cn.liuhulu.tool.Tools;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.text.Text;

public class MainController implements Initializable {

	// 产品页面对象
	@FXML
	TableView<Product> productTable;
	@FXML
	TableColumn<Product, String> productName, productSpec, productPrice;
	// 订单页面对象
	@FXML
	TableView<ProductBill> billTable;
	@FXML
	TableColumn<ProductBill, String> billName, billSpec, billQuantity, billPrice, billItemPrice;

	// 输入框
	@FXML // 算价中输入名字和数量进行价格计算，计算单笔交易的价格以及总价
	TextField name, quantity;
	@FXML // 新增中药，输入药品名称和药品规格以及药品价格，然后添加到数据中，数据需要持久化到磁盘。
	TextField nameText, specText, priceText;

	// 结果页
	@FXML
	Text itemToatal, itemCount, singlePrice;

	@Override
	public void initialize(URL arg0, ResourceBundle arg1) {
		// 初始化表格绑定数据
		initTableView();
		// 初始化辅助功能
		initAssist();

	}

	// -------------------------------------------------------------- UI操作
	public void initAssist() {
		// 药品数量只能输入数字
		quantity.textProperty().addListener((o, oldV, newV) -> {
			quantity.setText(newV.matches("\\d*") ? newV : oldV);
			singleCalculate();
		});
	}

	/**
	 * 初始化表格
	 */
	public void initTableView() {
		// 产品列表
		productName.setCellValueFactory(new PropertyValueFactory<>("name"));
		productSpec.setCellValueFactory(new PropertyValueFactory<>("spec"));
		productPrice.setCellValueFactory(new PropertyValueFactory<>("price"));
		productTable.setItems(Datas.syncDataToApp());
		// 选择其中某一行的时候
		productTable.getSelectionModel().selectedItemProperty().addListener((o, oldV, newV) -> {
			name.setText(newV == null ? name.getText() : newV.getName());
			singleCalculate();
		});

		// 订单列表
		billName.setCellValueFactory(new PropertyValueFactory<>("name"));
		billSpec.setCellValueFactory(new PropertyValueFactory<>("spec"));
		billPrice.setCellValueFactory(new PropertyValueFactory<>("price"));
		billQuantity.setCellValueFactory(new PropertyValueFactory<>("quantity"));
		// 订单数量可以修改，修改后需要重新计算价格
		billQuantity.setCellFactory(i -> new EditingCell<ProductBill>());
		billQuantity.setOnEditCommit(i -> {
			i.getTableView().getItems().get(i.getTablePosition().getRow()).setQuantity(i.getNewValue()).setItemPrice();
			synthesizeCalculateon();
		});

		billItemPrice.setCellValueFactory(new PropertyValueFactory<>("itemPrice"));

	}

	/**
	 * 搜索
	 */
	@FXML
	public void search(ActionEvent event) {
		String searchName = name.getText();
		if (!searchName.isEmpty()) {
			ObservableList<Product> productSearch = FXCollections.observableArrayList(
					productTable.getItems().stream().filter(i -> i.getName().contains(searchName)).collect(Collectors.toList()));
			productTable.getSelectionModel().clearSelection();
			productTable.setItems(productSearch);
			productTable.refresh();
			if (productSearch.size() == 1) {
				productTable.getSelectionModel().select(0);
			}
		} else {
			productTable.setItems(Datas.syncDataToApp());
			productTable.refresh();
		}
	}

	/**
	 * 重置
	 */
	@FXML
	public void reset(ActionEvent event) {
		name.setText("");
		search(event);
		quantity.setText("1");
		productTable.getSelectionModel().clearSelection();
		singleCalculate();
		// 清理新增中药中的数据
		nameText.setText("");
		specText.setText("");
		priceText.setText("");
	}

	/**
	 * 添加产品账单
	 */
	@FXML
	public void addProductBill(ActionEvent event) {
		synthesizeCalculateon();
		reset(event);
	}

	/**
	 * 添加产品
	 */
	@FXML
	public void addProduct(ActionEvent event) {
		String name = nameText.getText().trim();
		if (name.isEmpty()) {
			AlertMaker.showSimpleAlert("提示信息", "请输入中药名称");
			return;
		}
		String spec = specText.getText().trim();
		if (spec.isEmpty()) {
			AlertMaker.showSimpleAlert("提示信息", "请输入中药规格");
			return;
		}
		String price = priceText.getText().trim();
		// 价格不是空，满足是数字或是小数
		if (price.isEmpty() || !(Tools.isNumber(price)||Tools.isDecimal(price))) {
			AlertMaker.showSimpleAlert("提示信息", "请输入中药单价,只能是整数或者小数");
			return;
		}
		// 每次新增产品会增加到产品列表的第一位
		productTable.getItems().add(0, new Product(name, spec, price));
		// 将数据同步到磁盘上
		Datas.syncDataToLoad(productTable.getItems());
		// 添加产品后重置白哦但数据
		reset(null);
	}

	@FXML
	public void newBill() { // 新建订单
		reset(null);
		billTable.getItems().clear();
		synthesizeCalculateon();
	}

	/**
	 * 添加数量
	 */
	@FXML
	public void addQuantity(ActionEvent event) {
		Button btn = (Button) event.getSource();
		String now = quantity.getText().trim();
		if (now.isEmpty()) {
			now = "0";
		}
		quantity.setText(String.valueOf(Integer.valueOf(now) + Integer.valueOf(btn.getAccessibleText())));
	}
	
	@FXML // 产品列表右键中的刷新按钮
	public void refreshProduct(ActionEvent event) {
		// 先清空列表中所有的数据
		productTable.getItems().clear();
		// 加载磁盘中所有数据
		productTable.setItems(Datas.syncDataToApp());
	}

	@FXML // 删除选中产品
	public void deleteProduct(ActionEvent event) {
		int removeId = productTable.getSelectionModel().getSelectedIndex();
		if (removeId >= 0) {
			productTable.getItems().remove(productTable.getSelectionModel().getSelectedIndex());
		}
		// 将数据同步到磁盘上
		Datas.syncDataToLoad(productTable.getItems());
	}

	@FXML // 删除全部产品
	public void deleteAllProduct(ActionEvent event) {
		if (AlertMaker.showAffirmMessage("提示信息", "确认删除列表中所有的中药数据价格？\n【注：软件目录下按照日期会备份操作数据。】")) {
			productTable.getItems().clear();
			return;
		}
//		 将数据同步到磁盘上
		Datas.syncDataToLoad(productTable.getItems());
	}

	@FXML // 删除订单
	public void deleteBill(ActionEvent event) {
		int removeId = billTable.getSelectionModel().getSelectedIndex();
		if (removeId >= 0) {
			billTable.getItems().remove(billTable.getSelectionModel().getSelectedIndex());
		}
	}

	// -------------------------------------------------------------------------------
	// 数据操作

	/**
	 * 单项价格计算，当产品页面发生变化的时候，去计算产品的结果，并更新到页面显示
	 * 
	 */
	private ProductBill singleCalculate() { // 单项计算
		Product selectedItem = productTable.getSelectionModel().getSelectedItem();
		if (selectedItem != null && !quantity.getText().isEmpty()) {
			Optional<String> multiply = Tools.multiply(selectedItem.getPrice(), quantity.getText());
			singlePrice.setText(multiply.isPresent() ? multiply.get() : "0.0");
			// 返回产品对象
			return new ProductBill(selectedItem, quantity.getText());
		}
		singlePrice.setText("0.0");
		return null;
	}

	/**
	 * 计算表单内所有价格
	 */
	private void synthesizeCalculateon() {
		ProductBill productBill = singleCalculate();
		if (productBill != null) {
			billTable.getItems().add(productBill);
		}
		// 总条目
		itemCount.setText(String.valueOf(billTable.getItems().size()));
		// 总价格
		itemToatal.setText(billTable.getItems().isEmpty() ? "0.0": billTable.getItems().stream().map(l -> l.getItemPriceDouble()).reduce(Double::sum).get().toString());
		billTable.refresh();
	}

}
